class ReportsController < ApplicationController

  # Utilizes the open_flash_charts objects to create the graphs for the reports requring such.
  def index
    @timePiegraph = open_flash_chart_object(600,300,"/reports/pie_graph_code")
    #@tracesLineGraph = open_flash_chart_object(600,300,"/reports/traces_by_day_code")
    #@minsPerDayGraph = open_flash_chart_object(600,300,"/reports/hours_by_day_code")
    @hourAndTracesByDay = open_flash_chart_object(600,300, url_for( :action => 'hours_and_traces_by_day_code', :params => {:event_id => params[:event_id], :show_zero_days => params[:show_zero_days]}))
  end

  # Gathers trace information for a given event; if there is no information yet, a redirect is given with a flash[:error] setup.
  # Otherwise, this will use the event_minutes_by_day_code to display traced minutes over time.
  def byevent
    if params[:event_id].nil?
      redirect_to(:action => "index", :controller => :reports)
    end
    
    @thisEvent = Event.find_by_id(params[:event_id])
    
    #Quick check to find events with no traces
    if @thisEvent.traces.count == 0
      flash[:error] = 'No traces for this event yet.'
      redirect_to :action => :index
    end
    @eventTitle = @thisEvent.title
    @eventMinsByDay = open_flash_chart_object(600,300, url_for( :action => 'event_minutes_by_day_code', :params => {:event_id => params[:event_id], :show_zero_days => params[:show_zero_days]}))
  end
  
  # Returns a list of traces, grouped by day
  def byday 
    @traces = Trace.find :all, :order => 'created_at DESC'
    @traces_by_day = @traces.group_by {|t| t.created_at.beginning_of_day}

    respond_to do |format|
      format.html
    end    
  end
  
  # Returns a list of events, with each day having grouped traces.
  # More work could be done here, to keep some of the logic out of the related view.
  def byeventdays
    @dateFrom = Time.new.beginning_of_week
    @dateTo = Time.new.end_of_week
 
    if !params[:dateFrom].nil?
      @dateFrom = Date.civil(params[:dateFrom][:year].to_i,params[:dateFrom][:month].to_i,params[:dateFrom][:day].to_i).beginning_of_day
    end
    if !params[:dateTo].nil?
      @dateTo = Date.civil(params[:dateTo][:year].to_i,params[:dateTo][:month].to_i,params[:dateTo][:day].to_i).end_of_day
    end

    @traces = Trace.find :all, :conditions => [ "created_at between ? and ?", @dateFrom, @dateTo], :order => 'created_at ASC'
    @traces_by_event = @traces.group_by {|t| t.event_id}
  
    render :partial => "byeventDays", :layout => true
  end
  
  # Returns the traces entered into the system for a given date range
  # If no date range parameters are given, it uses "this week" as the default.
  def byrange
    @dateFrom = Time.new.beginning_of_week
    @dateTo   = Time.new.end_of_week
    
    if !params[:dateFrom].nil?
      @dateFrom = Date.civil(params[:dateFrom][:year].to_i,params[:dateFrom][:month].to_i,params[:dateFrom][:day].to_i).beginning_of_day
    end
    if !params[:dateTo].nil?
      @dateTo = Date.civil(params[:dateTo][:year].to_i,params[:dateTo][:month].to_i,params[:dateTo][:day].to_i).end_of_day
    end
    
    @traces = Trace.find :all, :conditions => [ "created_at between ? and ?", @dateFrom, @dateTo], :order => 'created_at ASC'
    @traces_by_day_this_week = @traces.group_by {|t| t.created_at.beginning_of_day}
    render :partial => "byrange", :layout => true
  end
  
  ######################################
  ## OPEN FLASH CHART CODE
  ######################################
  
  # Generates an open flash chart for the event minutes by day report
  def event_minutes_by_day_code
    @minCounts = Array.new()
    @avgCounts = Array.new()
    @xLabels = Array.new()
    @max = 0

    @event = Event.find_by_id(params[:event_id])
    @traces = Trace.find :all, :order => 'created_at ASC', :conditions => {:event_id => @event.id}
    
    @dateRangeHash = Hash.new
    @dateRangeHash[:Mins] = Hash.new
    @dateRangeHash[:Avgs] = Hash.new
    
    @firstDay = @traces[0].created_at.beginning_of_day.to_date
    @today = Date.today.beginning_of_day.to_date
    (@firstDay..@today).each do |d|
      @dateRangeHash[:Mins][d.to_s] = 0
      @dateRangeHash[:Avgs][d.to_s] = 0
    end
       
    @trace_days = @traces.group_by {|t| t.created_at.beginning_of_day}
    @trace_days.sort.each do |day, traces|
      @mins_this_day = traces.sum(&:minSpent)
      @minCounts << @mins_this_day
      @avg_this_day = @minCounts.inject(0){|sum,item| sum + item} / @minCounts.size
      @avgCounts << @avg_this_day
      
      if @mins_this_day > @max
        @max = @mins_this_day + 10
      end

      @dateRangeHash[:Mins][day.to_date.to_s] = @mins_this_day
      @dateRangeHash[:Avgs][day.to_date.to_s] = @avg_this_day
      @xLabels << day.to_date.to_s
    end
    
    if(params[:show_zero_days])
      @avgCounts = Array.new
    
      @xLabels = @dateRangeHash[:Mins].keys.to_a.sort
      @minCounts = Array.new
      @avgCounts = Array.new
      @xLabels.each do |l|
          @minCounts << @dateRangeHash[:Mins][l]
          @avgCounts << @dateRangeHash[:Avgs][l]
      end
    end
        
    title = Title.new("Mins by Day for #{@event.title}")
    dataMins = @minCounts
    dataAvgs = @avgCounts
    
    line_Mins = LineDot.new
    line_Mins.text = "Mins"
    line_Mins.width = 4
    line_Mins.colour = '#DFC329'
    line_Mins.dot_size = 5
    line_Mins.values = dataMins

    line_Avgs = LineDot.new
    line_Avgs.text = "Avg"
    line_Avgs.width = 2
    line_Avgs.colour = '#57BCD9'
    line_Avgs.dot_size = 2
    line_Avgs.values = dataAvgs
    
    y = YAxis.new
    y.set_range(0,@max,30)

    x = XAxis.new
    x_labels = XAxisLabels.new
    x_labels.set_vertical()
    x_labels.labels = @xLabels
    x.set_labels(x_labels)
    
    y_legend = YLegend.new("")
    y_legend.set_style('{font-size: 10px; color: #770077}')
    
    x_legend = XLegend.new("Days")
    x_legend.set_style('{font-size: 10px; color: #770077}')
    
    chart = OpenFlashChart.new
    chart.set_title(title)
    chart.set_y_legend(y_legend)
    chart.set_x_legend(x_legend)
    chart.y_axis = y
    chart.x_axis = x
    
    chart.add_element(line_Mins)
    chart.add_element(line_Avgs)
    
    render :text => chart.to_s      
  end
  
  # Generates an open flash chart for the hours and traces per day report
  def hours_and_traces_by_day_code
    @hourCounts = Array.new()
    @traceCounts = Array.new()
    @avgCounts = Array.new()
    @xLabels = Array.new()
    @max = 0
    
    @traces = Trace.find(:all, :order => 'created_at ASC, id')
    
    @dateRangeHash = Hash.new
    @firstDay = @traces[0].created_at.beginning_of_day.to_date
    @today = Date.today.beginning_of_day.to_date
    (@firstDay..@today).each do |d|
      @dateRangeHash[d.to_s] = [0,0]
    end
    
    @trace_days = @traces.group_by {|t| t.created_at.beginning_of_day}
    @trace_days.sort.each do |day, traces|
      @tracesThisDay = traces.size
      @traceCounts << @tracesThisDay
      @avg_this_day = @traceCounts.inject(0){|sum,item| sum + item} / @traceCounts.size
      @avgCounts << @avg_this_day
    
      @mins_this_day = 0
      traces.each do |tr|
        @mins_this_day += tr.minSpent
      end
      @hours_this_day = (@mins_this_day.to_f/60)
      @hourCounts << @hours_this_day
        
      if @hours_this_day > @max
        @max = @hours_this_day + 2
      end
      if @tracesThisDay > @max
        @max = @tracesThisDay +  2
      end
      
      @dateRangeHash[day.to_date.to_s][0] = @hours_this_day
      @dateRangeHash[day.to_date.to_s][1] = @tracesThisDay
      @dateRangeHash[day.to_date.to_s][2] = @avg_this_day
      @xLabels << day.to_date
    end
    
    if(params[:show_zero_days])
      @xLabels = @dateRangeHash.keys.to_a.sort
      @hourCounts = Array.new
      @traceCounts = Array.new
      @avgCounts = Array.new
      @xLabels.each do |l|
          @hourCounts << @dateRangeHash[l][0]
          @traceCounts << @dateRangeHash[l][1]
          @avgCounts << @dateRangeHash[l][2]
      end
    end
    
    title = Title.new("Hours and Traces by Day")
    dataHours = @hourCounts
    dataTraces = @traceCounts
    dataAvgs = @avgCounts
    
    line_Hours = LineDot.new
    line_Hours.text = "Hours"
    line_Hours.width = 4
    line_Hours.colour = '#DFC329'
    line_Hours.dot_size = 5
    line_Hours.values = dataHours
    
    line_Traces = LineHollow.new
    line_Traces.text = "Traces"
    line_Traces.width = 1
    line_Traces.colour = '#2F74D0'
    line_Traces.dot_size = 5
    line_Traces.values = dataTraces

    line_Avgs = LineDot.new
    line_Avgs.text = "Trace Avg"
    line_Avgs.width = 2
    line_Avgs.colour = '#57BCD9'
    line_Avgs.dot_size = 2
    line_Avgs.values = dataAvgs    
    
    y = YAxis.new
    y.set_range(0,@max,2)

    x = XAxis.new
    x_labels = XAxisLabels.new
    x_labels.set_vertical()
    x_labels.labels = @xLabels
    x.set_labels(x_labels)
    
    y_legend = YLegend.new("")
    y_legend.set_style('{font-size: 10px; color: #770077}')
    
    x_legend = XLegend.new("Days")
    x_legend.set_style('{font-size: 10px; color: #770077}')
    
    chart = OpenFlashChart.new
    chart.set_title(title)
    chart.set_y_legend(y_legend)
    chart.set_x_legend(x_legend)
    chart.y_axis = y
    chart.x_axis = x
    
    chart.add_element(line_Hours)
    chart.add_element(line_Traces)
    chart.add_element(line_Avgs)
    
    render :text => chart.to_s      
  end

  # Generates a nifty open flash chart pie graph, showing a spread of the time spent.
  def pie_graph_code
    # based on this example - http://teethgrinder.co.uk/open-flash-chart-2/pie-chart.php
    title = Title.new("Spread of Time Spent
    
    ")

    pie = Pie.new
    pie.start_angle = 35
    pie.animate = true
    pie.tooltip = '#val# of #total#<br>#percent# of 100%'
    pie.colours = ["#d01f3c", "#356aa0", "#C79810", "#8CEFFD", "#FF73B9", "#A3FEBA", "#7979FF"]

    x = Array.new()
    
    traces = Trace.sum(:minSpent, :group => :event_id)
    a = Array.new()
    traces.each do |t|
      a << [t[1],Event.find_by_id(t[0]).title]
    end
    
    a.each do |t|
      x << PieValue.new(t[0],t[1])
    end
    pie.values = x

    #pie.values  = [2,3, PieValue.new(6.5,"Hello (6.5)")]

    chart = OpenFlashChart.new
    chart.title = title
    chart.add_element(pie)

    chart.x_axis = nil

    render :text => chart.to_s

  end  
end
